<%@ Page Language="C#" ValidateRequest="false" Debug="false" Trace="false" Async="true"%>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Diagnostics" %>

<script language="C#" runat="server">
    private SqlConnection con;
    private const string coninfo = "server=x.sqlserver.rds.aliyuncs.com,3433;database=hs_db;uid=user;pwd=password";
    private const int poolsize = 10;
    private string currentpoolname = string.Empty;
    private const string thisname = "db_Fokite_Com.log";
    private TextWriterTraceListener mainloglisen;

    void Page_load(object sender, EventArgs e) {
        //string strpath = Server.MapPath(".");
        //var filenamelog = Path.Combine(strpath,thisname);
        //mainloglisen = new TextWriterTraceListener(filenamelog);
        //Trace.Listeners.Add(mainloglisen);
        //Response.Write(filenamelog);
        var completesize = HttpRuntime.Cache.Get("completesize");
        if (completesize == null)
        {
            for (int i = 0; i < poolsize; i++)//顺序开启固定池
            {
                fokiteaddcon(i);
            }
            HttpRuntime.Cache.Insert("completesize", poolsize, null, DateTime.Now.AddMinutes(2).AddSeconds(30), Cache.NoSlidingExpiration);
        }
        else
        {
            fokiteaddcon();
            //WebClient wc = new WebClient();
            //wc.DownloadDataTaskAsync("http://127.0.0.1/self.html");
            //wc.Dispose();
        }


    }

    //void StateChangeEvent(object sender, StateChangeEventArgs e) {
    //    Trace.Write("在事件中：");
    //    Trace.Write(e.OriginalState.ToString());
    //    Trace.Write(e.CurrentState.ToString());

    //    IEnumerable<string> contents = new string[]
    //    {
    //        string.Concat( "原始状态和当前状态：", e.OriginalState.ToString() , e.CurrentState.ToString() )
    //    };

    //    //var r = fokiteaddcon();

    //    if ( (e.OriginalState == e.CurrentState) && e.CurrentState == ConnectionState.Closed )
    //    {
    //        Trace.Write("这回真关了：");
    //        Trace.Write(e.CurrentState.ToString());
    //        contents.Concat(new string[] { currentpoolname });

    //    }
    //    simplog(contents);

    //}

    void simplog(IEnumerable<string> contents)
    {
        string strpath = Server.MapPath(".");
        var filenamelog = Path.Combine(strpath,thisname);
        File.AppendAllLines(filenamelog,contents);

    }

    SqlConnection fokiteaddcon(params int[] i)
    {
        if(i.Length == 0)
        {
            var ra = new Random();
            i = new int[] { ra.Next(10) };
        }


        var sname = string.Concat("fokite_pool_", Convert.ToInt32(i[0]) );
        this.currentpoolname = sname;
        con = HttpRuntime.Cache.Get(currentpoolname) as SqlConnection;

        var hcodeinfo = HttpRuntime.Cache.Get(string.Concat(currentpoolname, "_hcode")) ;

        Trace.Write("在构建方法中：");
        Trace.Write(currentpoolname);
        //Trace.Write(hcodeinfo.ToString());

        while (con == null || con.State == ConnectionState.Executing)
        {
            try
            {

                con = new SqlConnection();
                con.ConnectionString = coninfo;
                //con.StateChange += StateChangeEvent;
                con.Open();

                Trace.Write("这是一个新建对象：");
                //var hcode = con.GetHashCode();
                //KeyValuePair<string, string> a = new KeyValuePair<string, string>(string.Concat(hcode,"_fokite"),currentpoolname);

                //Trace.Write(a.ToString());

                //HttpRuntime.Cache.Insert(string.Concat(currentpoolname,"_hcode"), con, null, DateTime.Now.AddMinutes(2), Cache.NoSlidingExpiration);
                HttpRuntime.Cache.Insert(currentpoolname, con, null, DateTime.Now.AddMinutes(2), Cache.NoSlidingExpiration);

            }
            catch (Exception ex)
            {
                Trace.Write(ex.Message);
                break;
            }
        }
        if (con.State != ConnectionState.Open )
        {
            con.Open();
        }
        return con;
    }
</script>

<%
    //Response.ClearContent();

    string resultjson = "\"data\":{0},\"error\":{1},\"nonquery\":{2},\"cache\":{3}";
    string rjson = "[]";
    string error = "\"204\"";
    string nonquery = "\"\"";
    string lastsql = string.Empty;
    string sqldbtype = string.Empty;
    string reqtype = Request.Headers["x-api-mingling"] == null ? "HEAD" : Request.Headers["x-api-mingling"].ToUpper(); // Request.RequestType.ToUpper();
    var cacheinfo = new Dictionary<string,object>();

    //Response.Write (Request.Headers["x-api-mingling"]);

    Dictionary<string, object> bodyjson;

    Stream stream = Request.InputStream;

    string bodycontent = string.Empty;
    using (var reader = new StreamReader(stream, Request.ContentEncoding))
    {
        bodycontent = reader.ReadToEnd();
    }

    if (string.IsNullOrEmpty(bodycontent)) { Response.End(); }

    var jsons = new JavaScriptSerializer();

    var parameter = new Dictionary<string, object>();

    if (Request.ContentType == "application/json")//如果是JSON 就肯定是对表进行写操作
    {
        //约束传输的JSON
        //{"sql":"SELECT * FROM [hs_db].[dbo].[hs_m2m_ec_dbs] where [name] = @name","parameter":{"@name":["namedd"]}}
        //{sql:string,parameter:{value:{1,int},valuen:{2,long}}} 
        try
        {
            bodyjson = jsons.DeserializeObject(bodycontent) as Dictionary<string, object>;
            //解析出SQL
            var tablename = bodyjson["sql"] ;
            lastsql = tablename.ToString();

            if (bodyjson.ContainsKey("parameter"))
            {
                parameter = bodyjson["parameter"] as Dictionary<string, object>;
            }

        }
        catch (Exception ex)
        {
            //error = "JSON格式不对哟~";

            error = string.Concat('"', ex.Message ,'"');

            //Response.StatusCode = 500;,ex.StackTrace
            //throw new HttpException(500,error);//这里挖坑 ，怎么把500错误合理抛出去
        }
    }

    SqlCommand command = null;
    try
    {
        command = new SqlCommand();
        command.Connection = con;
        command.CommandType = CommandType.Text;
    }
    catch (Exception ex)
    {
        error = string.Concat('"', ex.Message, '"');
    }

    command.CommandText = lastsql;

    foreach (KeyValuePair<string,object> pre in parameter)
    {
        try
        {
            object[] types = pre.Value as object[];
            //Response.Write(types.Length);

            var p = new SqlParameter();
            p.ParameterName = pre.Key;
            p.Value = types[0];

            if (types.Length > 1)
            {
                p.SqlDbType = (SqlDbType)Enum.Parse(typeof(SqlDbType), types[1].ToString());
            }
            if (types.Length > 2)
            {
                p.Size = (int)types[1];
            }

            command.Parameters.Add(p);
        }catch(Exception ex)
        {
            error = string.Concat('"', ex.Message,ex.StackTrace ,'"');
        }


    }

    try
    {
        var details = new Dictionary<string, object>();
        object[] r = new object[1];

        switch (reqtype)//HttpRequest.HttpMethod
        {
            case "POST"://update //del                
                nonquery = command.ExecuteNonQuery().ToString();
                break;
            case "DELETE":
                command.CommandType = CommandType.StoredProcedure;
                command.ExecuteScalarAsync();
                ; break;
            case "HEAD":
                r[0] = command.ExecuteScalarAsync();
                rjson = jsons.Serialize(r);
                ; break;
            case "PUT"://insert 
                command.ExecuteNonQuery();
                command.CommandText = "SELECT SCOPE_IDENTITY();";
                r[0] = command.ExecuteScalar();
                rjson = jsons.Serialize(r);
                ; break;
            default://select 
                List<Dictionary<string, object>> h = new List<Dictionary<string, object>>();
                using (SqlDataReader rdr = command.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        details = Enumerable.Range(0, rdr.FieldCount)
                           .ToDictionary(
                          i => rdr.GetName(i),
                          i => rdr.GetValue(i)
                          );
                        h.Add(details);
                    }
                }
                rjson = jsons.Serialize(h);
                //Response.Write(resultjson); 
                ; break;
        }
    }
    catch (Exception ex)
    {
        error = string.Concat('"', ex.Message,ex.StackTrace ,'"');
    }
   

    var cacheinfos = jsons.Serialize(cacheinfo);
    string lastresut = string.Format(resultjson, rjson, error, nonquery,cacheinfos);

    Response.Write("{");
    Response.Write(lastresut);
    Response.Write("}");


    //Response.BinaryWrite();
%>